﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using HtmlAgilityPack;
using MiniCrawler.DataAccess;
using MiniCrawler.DataAccess.Repositories;
using MiniCrawler.Downloader.ResourceDownloader;
using MiniCrawler.Entity;
using Newtonsoft.Json;

namespace MiniCrawler.Business.Collectors.ResourceCollectors
{
    public class Book
    {
        public string BookId { get; set; }
        public string Name { get; set; }
        public string Isbn { get; set; }
        public string FullIsbn { get; set; }
        public string Author { get; set; }
        public string Description { get; set; }
        public string Image { get; set; }
        public string PriceString { get; set; }
        public float Price { get; set; }
        public string FolderName { get; set; }
    }

    public class Alibris : ResourceLinkCollector, IResourceCollector
    {
        private string hostName;

        public Alibris(string hostName, int level)
            : base(hostName, level)
        {
            this.hostName = hostName;
        }

        private Book GetData(string data)
        {
            // Load data
            var doc = new HtmlDocument();
            doc.LoadHtml(data);

            var booknameString =
               "//div[@id='detail']/div[@class='detail']/div/h1/span";
            var authornameString =
                "//div[@id='detail']/div[@class='detail']/div/p/a";
            var bookdescriptionString =
                "//p[@class='synopsis']/span[@id='synopsis-detail']";

            var fullIsbnString = "//div[@id='detail']/div[@class='detail']/h2";

            var buynewPriceString =
                "//table[@class='available-copies']";
            var imgString = "//div[@id='bookSearchN']/div[@class='sidebar'][1]/div[@class='sidebar-hero']/img";

            var hiddenWorkIdString = "//input[@id='hiddenWorkid']";
            var hiddenIsbnString = "//input[@id='hiddenIsbn']";

            // Get nodes
            var detailNode = doc.DocumentNode.SelectSingleNode(bookdescriptionString);
            var nameNode = doc.DocumentNode.SelectSingleNode(booknameString);
            var authorNode = doc.DocumentNode.SelectSingleNode(authornameString);
            var fullIsbnNode = doc.DocumentNode.SelectSingleNode(fullIsbnString);
            var buynewpriceNode = doc.DocumentNode.SelectNodes("//td[@class='price']");
            var imgstringNode = doc.DocumentNode.SelectSingleNode(imgString);
            var hiddenIsbnNode = doc.DocumentNode.SelectSingleNode(hiddenIsbnString);
            var hiddenWorkIdNode = doc.DocumentNode.SelectSingleNode(hiddenWorkIdString);

            // Create book instance
            var book = new Book();
            if (nameNode != null) book.Name = nameNode.InnerText;
            if (detailNode != null) book.Description = detailNode.InnerText;
            if (authorNode != null) book.Author = authorNode.InnerText;

            if (fullIsbnNode != null)
            {
                book.FullIsbn = fullIsbnNode.InnerText;
            }
            else
            {
                book.FullIsbn = string.Empty;
            }
            if (buynewpriceNode != null && buynewpriceNode.Count > 2)
            {

                book.PriceString = buynewpriceNode[1].InnerText;

                float defaultValue = 0;
                float.TryParse(book.PriceString.Replace("$", ""), out defaultValue);
                book.Price = defaultValue;
            }

            if (imgstringNode != null)
            {
                book.Image = Utils.GetAttribute(imgstringNode, "src");
            }

            if (hiddenIsbnNode != null)
            {
                book.Isbn = Utils.GetAttribute(hiddenIsbnNode, "value");
            }
            if (hiddenWorkIdNode != null)
            {
                book.BookId = Utils.GetAttribute(hiddenWorkIdNode, "value");
            }


            // Processing text
            // \ / : | ? * "
            string folderName = book.Name;
            if (!string.IsNullOrEmpty(book.Isbn)) folderName = book.Isbn + " - " + book.Name;
            else
            {
                if (!string.IsNullOrEmpty(book.BookId)) folderName = book.BookId + " - " + book.Name;
            }
            string processedText =
                (folderName)
                    .Replace("&gt;", ">")
                    .Replace("&raquo;", ">")
                    .Replace("&amp;", "-")
                    .Replace(">", "\\")
                    .Replace("»", "\\")
                    .Replace('&', '-')
                    .Replace("/", string.Empty)
                    .Replace("|", string.Empty)
                    .Replace("?", string.Empty)
                    .Replace("*", string.Empty)
                    .Replace("\"", string.Empty)
                    .Replace(":", string.Empty)
                    .Replace("\r", string.Empty)
                    .Replace("\n", string.Empty)
                    .Replace("\t", string.Empty);
            if (processedText.Length > 255) processedText = processedText.Substring(0, 255);
            book.FolderName = folderName;
            return book;
        }

        public string GetFolderPath(string data)
        {
            throw new NotImplementedException();
        }

        public List<string> GetResourcePatterns()
        {
            return new List<string>();
        }

        public void GetLinks()
        {
            foreach (var dataLink in Urls)
            {
                string data = Common.GetWebPage(Common.FillAbsoluteUrl(hostName, dataLink.Value));
                if(!string.IsNullOrEmpty(data))
                {
                    var book = GetData(data);

                    var downloadLink =
                                new DownloadLink
                                {
                                    Path = book.FolderName,
                                    Value = book.Image,
                                    Website = dataLink.Website,
                                    IsDownloaded = false
                                };

                    if (!string.IsNullOrEmpty(book.Isbn)) downloadLink.Url = book.Isbn;
                    else
                    {
                        if (!string.IsNullOrEmpty(book.BookId)) downloadLink.Url = book.BookId;
                    }

                    downloadLink.Description = JsonConvert.SerializeObject(book);

                    DownloadLinkHelper.CreateLink(downloadLink);

                    DataLinkHelper.UpdateLink(dataLink.Value);
                }
            }
        }

        public void FixUrls()
        {
            DownloadLinkHelper.FixPathUrl(hostName);
        }
    }
}
